#ifndef _THREAD_H
#define _THREAD_H
#include <iostream>
#include <string>
#include <pthread.h>
#include <cstring>
#include <functional>
#include <unistd.h>
using namespace std;
namespace ThreadModlue
{
    static uint32_t number = 1; // 计数器
    template <typename T>
    class Thread
    {
        using func_t = function<void(T)>; // 线程函数类型

    private:
        void EnableDetach()
        {
            cout<<"enable detach"<<endl;
            _isdetach = true;
        }

    public:
        Thread(func_t func,T data)
            : _tid(0)
            , _isdetach(false)
            , _isrunning(false)
            , res(nullptr)
            , _func(func)
            ,_data(data)
        {
            _name = "thraed-" + to_string(number++);
        }
        void Detach()
        {
            // 如果线程已经分离了的话那么我们就不需要再次进行的分离操作了
            if (_isdetach)
                return;
            if (_isrunning)
                pthread_detach(_tid);
            // 如果没有运行的话，就将标志位设置为1，然后我们在Start的时候会进行分离操作
            EnableDetach(); // 标志位设置为true
        }
        void EnableRunning()
        {
            _isrunning = true;
        }
        // 下面的函数是类里面的函数，默认包含this指针
        static void *Routine(void *args) // 这里还藏着一个this指针，所以参数类型是不兼容的
        {
            // 下面就是如何类内处理回调函数
            Thread<T> *self = static_cast<Thread<T>*>(args); // 这里的this指针就是我们传入的参数
            self->EnableRunning();

            if (self->_isdetach) // 如果线程是被设置过分离的
                self->Detach();
            pthread_setname_np(pthread_self(), self->_name.c_str()); // 设置线程名
            self->_func(self->data); // 调用线程函数
            return nullptr;
        }
        bool Start()
        {
            // 线程不能重复启动，如果已经启动过了，那么就不需要再次启动了
            if (_isrunning)
                return false;
            int n = pthread_create(&_tid, nullptr, Routine, this);
            if (n != 0) // 创建线程出错了
            {
                cout << "创建线程失败" << strerror(n) << endl;
                return false;
            }
            else
            {
                cout << _name << "线程创建成功" << endl;
                return true;
            }
        }
        bool Stop()
        {
            if (_isrunning) // 线程必须是运行的，我们才能stop
            {
                int n = pthread_cancel(_tid); // 发送取消请求
                if (n != 0)                   // 取消失败了
                {
                    cerr << "取消线程失败" << strerror(n) << endl;
                    return false;
                }
            }
            else
            {
                _isrunning = false; // 标记线程为停止状态
                cout << _name << "线程已经停止" << endl;
                return true;
            }
            return false;
        }
        void join()
        {
            if (_isdetach)
            {
                cout << "线程已经分离,不能进行join操作" << endl;
                return; // 如果是分离的话那么我们就得return
                // 线程不管运行没都是可以进行join的
            }
            int n = pthread_join(_tid, &res);
            if (n != 0)
            {
                cerr << "等待线程失败" << strerror(n) << endl;
            }
            else
            {
                cout << "join success" << endl;
            }
        }
        ~Thread()
        {
        }

    private:
        pthread_t _tid;
        string _name;
        bool _isdetach;  // 是否被分离的状态
        bool _isrunning; // 是否正在运行的状态
        void *res;       // 返回值
        func_t _func;    // 线程函数
        T _data;         // 线程函数的参数
    };
}

#endif